package com.yuehuanghun.admin.generator.model.generator;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yuehuanghun.admin.generator.model.Table;
import com.yuehuanghun.framework.exception.PlatformException;
import com.yuehuanghun.framework.exception.ValidateException;
import com.yuehuanghun.framework.json.JSONObject;
import com.yuehuanghun.framework.util.DatabaseUtil;
import com.yuehuanghun.framework.util.StringUtils;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;

@Component
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MysqlTableGenerator extends AbstractTableGenerator {

    @Override
    public List<Table> getSimpleTableInfo(String tableName, String tableComment,
            Date createTimeBegin, Date createTimeEnd, int pageNum, int pageSize) {
        StringBuilder sql = new StringBuilder();
        sql.append(
                "SELECT table_name name, table_comment comment, create_time createTime, update_time updateTime FROM information_schema.tables")
                .append(" WHERE table_schema = (SELECT database())")
                .append(" AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'")
                .append(" AND table_name NOT IN (SELECT table_name FROM gen_table)");

        if (StringUtils.isNotBlank(tableName)) {
            sql.append(" AND table_name LIKE '%").append(tableName).append("%'");
        }
        if (StringUtils.isNotBlank(tableComment)) {
            sql.append(" AND table_comment LIKE '%").append(tableComment).append("%'");
        }
        if (createTimeBegin != null) {
            sql.append(" AND create_time >= '")
                    .append(DateUtil.format(createTimeBegin, DatePattern.NORM_DATETIME_FORMATTER))
                    .append("'");
        }
        if (createTimeEnd != null) {
            sql.append(" AND create_time <= '")
                    .append(DateUtil.format(createTimeEnd, DatePattern.NORM_DATETIME_FORMATTER))
                    .append("'");
        }

        PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> mapList = tableMapper.getForMap(sql.toString());

        List<Table> tableList = mapList.stream().map(item -> {
            JSONObject json = new JSONObject(item);
            Table table = new Table();
            table.setJdbcName(json.getString("name"));
            table.setTableComments(json.getString("comment"));
            table.setCreateTime(json.getDate("createTime"));
            table.setUpdateTime(json.getDate("updateTime"));
            return table;
        }).collect(Collectors.toList());

        Page<Table> page = new Page<>();
        page.setTotal(((Page<?>) mapList).getTotal());
        page.addAll(tableList);
        return page;

    }

    @Override
    public Table genTable(String tableName) {
        StringBuilder sql = new StringBuilder();
        sql.append(
                "SELECT TABLE_NAME `name`, TABLE_COMMENT `comment`, CREATE_TIME `createTime`, UPDATE_TIME `updateTime` FROM information_schema.TABLES")
                .append(" WHERE TABLE_SCHEMA = (SELECT database())")
                .append(" AND TABLE_NAME = '")
                .append(tableName).append("'");
        List<Map<String, Object>> mapList = tableMapper.getForMap(sql.toString());
        if(mapList.isEmpty()) {
            throw new ValidateException(String.format("表%s不存在", tableName));
        }

        Table table = new Table();
        JSONObject json = new JSONObject(mapList.get(0));
        table.setJdbcName(json.getString("name"));
        table.setTableComments(json.getString("comment"));
        table.setCreateTime(json.getDate("createTime"));
        table.setUpdateTime(json.getDate("updateTime"));
        
        Connection conn = getConnection();
        try {
        	DatabaseMetaData dbMetaData = conn.getMetaData();
            retriveTableColumns(table, dbMetaData, createIndexList(getIndexResultSet(dbMetaData, tableName)));
        } catch (SQLException e) {
            throw new PlatformException(e);
        } finally {
            closeConnection(conn);
        }
        
        return table;
    }

	@Override
	public String getDbName() {
		return DatabaseUtil.DataBase.MYSQL.getDbName();
	}

}
